using System;
using System.Collections.Generic;
using System.Text;
using Castle.ActiveRecord;
using NHibernate.Expression;
using System.Text.RegularExpressions;
using Castle.ActiveRecord.Queries;

namespace Old.KenEgozi.Com.Domain.Blog
{
	[ActiveRecord("Blog_Posts",Lazy=true)]
	public class Post : BlogBase<Post>
	{
		private static readonly Regex nonUrlCharactersFinder = new Regex("[^a-zA-Z0-9 ]", RegexOptions.Compiled);
		private static readonly Regex htmlTagsFinder = new Regex("<[^>]+/?>", RegexOptions.Compiled);

		private string _title;
		private string _permalink;
		private string _description;
		private string _content;
		private Blog _blog = null;
		private Author _author = null;
		private IList<Comment> _comments = new List<Comment>();
		private IList<Tag> _tags = new List<Tag>();
		
		[Property(Access = PropertyAccess.NosetterCamelcaseUnderscore)]
		[ValidateNotEmpty]
		public virtual string Title
		{
			get { return _title; }
			set
			{
				_title = value;
				if (string.IsNullOrEmpty(_permalink))
					CreatePermalink();
			}
		}

		public virtual void SetCreationDate(DateTime value)
		{
			_creationDate = value;
		}
		public virtual void SetUpdateDate(DateTime value)
		{
			_updateDate= value;
		}
		[Property(Access = PropertyAccess.NosetterCamelcaseUnderscore)]
		public virtual string Permalink
		{
			get { return _permalink; }
		}

		[Property]
		public virtual string Description
		{
			get { return _description; }
			set { _description = value; }
		}

		[Property(Access = PropertyAccess.NosetterCamelcaseUnderscore,ColumnType="StringClob" )]
		public virtual string Content
		{
			get { return _content; }
			set
			{
				_content  = value;
				if (string.IsNullOrEmpty(_description))
					CreateDescription();
			}
		}

		[BelongsTo("BlogId")]
		public virtual Blog Blog
		{
			get { return _blog; }
			set { _blog = value; }
		}

		[BelongsTo("AuthorId")]
		public virtual Author Author
		{
			get { return _author; }
			set { _author = value; }
		}

		[HasMany(Lazy = true, Access = PropertyAccess.NosetterCamelcaseUnderscore, Inverse=true, Cascade=ManyRelationCascadeEnum.AllDeleteOrphan)]
		public virtual IList<Comment> Comments
		{
			get { return _comments; }
		}

		[HasAndBelongsToMany(
			Lazy = true,
			Table = "Blog_PostTagging",
			ColumnKey = "PostId",
			ColumnRef = "TagId",
			Access = PropertyAccess.NosetterCamelcaseUnderscore)]
		public virtual IList<Tag> Tags
		{
			get { return _tags; }
		}

		public virtual void CreatePermalink()
		{
			string urlFriendlyTitle = nonUrlCharactersFinder.Replace(Title, "").Trim().Replace("  ", " ").Replace(' ', '-').ToLower();
			_permalink = string.Format("{0:yyyy/MM/dd}/{1}.aspx",
				_creationDate, urlFriendlyTitle);
		}
		private void CreateDescription()
		{
			_description = htmlTagsFinder.Replace(_content, "");
			if (_description.Length > 500)
				_description = _description.Substring(0, 500);
		}

		public static Post FindByPermalink(string permalink)
		{
			return FindOne(Expression.Eq("Permalink", permalink));
		}
		public static Post[] FindRecent(int maxPosts, params ICriterion[] criterias)
		{
			return Post.SlicedFindAll(0, maxPosts,
				new Order[] { Order.Desc("CreationDate") },
				criterias);
		}

		public static Post[] FindRecent(params ICriterion[] criterias)
		{
			return FindRecent(20, criterias);
		}
		public static Post[] FindRecent(int maxPosts, Blog blog)
		{
			return FindRecent(maxPosts, Expression.Eq("Blog", blog));
		}
		public static Post[] FindRecent(Blog blog)
		{
			return FindRecent(Expression.Eq("Blog", blog));
		}

		public static Post[] FindArchived(Blog blog, int year, int month)
		{
			string hql = @"
				from Post p
				where 
					p.Blog = ? and
					year(p.CreationDate) = ? and
					month(p.CreationDate) = ? 
				order by CreationDate desc";
			SimpleQuery<Post> q = new SimpleQuery<Post>(hql, blog, year, month);
			return q.Execute();
		}
	}
}
